
function clearElementContent(element){
	//const element = document.getElementById(divId);
	while (element.firstChild) {
	  element.removeChild(element.firstChild);
	}
}
 
async function replaceDivContentWithScriptsEnhanced(divId, newHtml) {
  const div = document.getElementById(divId);
  if (!div) {
    console.error(`Element with ID "${divId}" not found`);
    return;
  }

  try {
    // 创建文档片段提高性能
    const fragment = document.createRange().createContextualFragment(newHtml);
    
    // 先处理所有非script内容
    const nonScriptNodes = Array.from(fragment.childNodes)
      .filter(node => node.nodeName !== 'SCRIPT');
    
    clearElementContent(div);
	
    nonScriptNodes.forEach(node => div.appendChild(node.cloneNode(true)));
    
    // 然后按顺序处理所有script
    const scripts = Array.from(fragment.querySelectorAll('script'));
    for (const script of scripts) {
      await cloneAndExecuteScript(script);
    }
  } catch (error) {
    console.error('Error replacing div content:', error);
  }
}
 
async function cloneAndExecuteScript(script) {
  return new Promise((resolve) => {
    const newScript = document.createElement('script');
    
    // 复制所有属性
    Array.from(script.attributes).forEach(attr => {
      newScript.setAttribute(attr.name, attr.value);
    });
    
    // 处理内联脚本
    if (!script.src && script.textContent.trim()) {
      try {
        newScript.text = script.textContent;
        document.head.appendChild(newScript).remove();
        resolve();
      } catch (e) {
        console.error('Error executing inline script:', e);
        resolve();
      }
      return;
    }
    
    // 处理外部脚本
    if (script.src) {
      newScript.onload = () => {
        newScript.remove();
        resolve();
      };
      newScript.onerror = () => {
        console.error(`Failed to load script: ${script.src}`);
        newScript.remove();
        resolve();
      };
      document.head.appendChild(newScript);
    } else {
      resolve();
    }
  });
} 

/**
 * 安全替换元素内容并处理所有资源（脚本、样式）
 * @param {string|HTMLElement} target - 目标元素ID或元素对象
 * @param {string} newHtml - 要插入的新HTML内容
 * @param {object} [options] - 配置选项
 * @param {boolean} [options.preserveScriptOrder=true] - 是否保持脚本顺序执行
 * @param {boolean} [options.loadStylesFirst=true] - 是否先加载样式
 * @returns {Promise<void>}
 */
async function dynamicHtmlUpdate(target, newHtml, options = {}) {
  const {
    preserveScriptOrder = true,
    loadStylesFirst = true
  } = options;

  // 获取目标元素
  const element = typeof target === 'string' 
    ? document.getElementById(target)
    : target;
  
  if (!element) {
    console.error('目标元素不存在');
    return;
  }

  // 1. 清空目标元素
  element.replaceChildren();

  // 2. 创建文档片段并解析HTML
  const fragment = document.createRange().createContextualFragment(newHtml);

  // 3. 分类提取不同资源
  const { scripts, styles, links, otherNodes } = classifyNodes(fragment);

  // 4. 先插入非资源内容
  element.append(...otherNodes);

  // 5. 处理样式资源
  if (loadStylesFirst) {
    await processStyles(styles, links);
  }

  // 6. 处理脚本资源
  await processScripts(scripts, { preserveOrder: preserveScriptOrder });

  // 7. 如果未优先加载样式，则在最后加载
  if (!loadStylesFirst) {
    await processStyles(styles, links);
  }
}

/**
 * 分类提取不同类型的节点
 */
function classifyNodes(fragment) {
  const allNodes = Array.from(fragment.childNodes);
  
  return {
    scripts: allNodes.filter(node => node.nodeName === 'SCRIPT'),
    styles: allNodes.filter(node => node.nodeName === 'STYLE'),
    links: allNodes.filter(node => 
      node.nodeName === 'LINK' && 
      node.rel.toLowerCase() === 'stylesheet'
    ),
    otherNodes: allNodes.filter(node => 
      !['SCRIPT', 'STYLE', 'LINK'].includes(node.nodeName)
    )
  };
}

/**
 * 处理样式资源
 */
async function processStyles(styles, links) {
  // 处理内联样式
  for (const style of styles) {
    const newStyle = document.createElement('style');
    newStyle.textContent = style.textContent;
    document.head.appendChild(newStyle);
  }

  // 处理外部样式表
  const linkPromises = links.map(link => {
    return new Promise((resolve) => {
      const newLink = document.createElement('link');
      newLink.rel = 'stylesheet';
      newLink.href = link.href;
      
      newLink.onload = resolve;
      newLink.onerror = () => {
        console.error(`样式表加载失败: ${link.href}`);
        resolve();
      };
      
      document.head.appendChild(newLink);
    });
  });

  await Promise.all(linkPromises);
}

/**
 * 处理脚本资源
 */
async function processScripts(scripts, options = {}) {
  const { preserveOrder = true } = options;

  if (preserveOrder) {
    // 顺序执行脚本
    for (const script of scripts) {
      await loadScript(script);
    }
  } else {
    // 并行加载脚本
    const scriptPromises = scripts.map(script => loadScript(script));
    await Promise.all(scriptPromises);
  }
}

/**
 * 加载单个脚本
 */
function loadScript(script) {
  return new Promise((resolve) => {
    const newScript = document.createElement('script');
    
    // 复制所有属性
    Array.from(script.attributes).forEach(attr => {
      newScript.setAttribute(attr.name, attr.value);
    });

    // 内联脚本
    if (!script.src && script.textContent.trim()) {
      try {
        newScript.text = script.textContent;
        document.head.appendChild(newScript).remove();
        resolve();
      } catch (e) {
        console.error('内联脚本执行错误:', e);
        resolve();
      }
      return;
    }

    // 外部脚本
    if (script.src) {
      newScript.onload = resolve;
      newScript.onerror = () => {
        console.error(`脚本加载失败: ${script.src}`);
        resolve();
      };
      document.head.appendChild(newScript);
    } else {
      resolve();
    }
  });
}

/**
 * 动态替换容器内容，并确保 HTML、JavaScript、CSS 正确加载和执行
 * @param {string} containerId - 要替换的容器 ID
 * @param {string} newContent - 新内容（包含 HTML、JS、CSS）
 */
function replaceContentWithResources(containerId, newContent) {
  const container = document.getElementById(containerId);
  if (!container) {
    console.error(`Container with ID "${containerId}" not found.`);
    return;
  }

  // 1. 清空容器并插入新内容（此时脚本和样式不会自动加载）
  container.innerHTML = newContent;

  // 2. 处理所有 <style> 和 <link rel="stylesheet">（确保 CSS 生效）
  const styles = container.querySelectorAll('style, link[rel="stylesheet"]');
  styles.forEach((oldStyle) => {
    const newStyle = oldStyle.cloneNode(true); // 深拷贝
    document.head.appendChild(newStyle); // 插入到 head
    oldStyle.remove(); // 移除旧样式
  });

  // 3. 处理所有 <script>（确保 JS 执行）
  const scripts = container.querySelectorAll('script');
  scripts.forEach((oldScript) => {
    const newScript = document.createElement('script');

    // 拷贝所有属性（如 id, src, type, async, defer 等）
    Array.from(oldScript.attributes).forEach((attr) => {
      newScript.setAttribute(attr.name, attr.value);
    });

    // 处理内联脚本
    if (!oldScript.src) {
      newScript.textContent = oldScript.textContent;
    }

    // 插入到 body，触发执行（外部脚本会自动加载）
    document.body.appendChild(newScript);
    oldScript.remove(); // 移除旧脚本
  });
}
